on OpenModule me,module
  m = me.getModuleAndFnList(module)
  repeat with i = 1 to m[2].count
    setProp(me,m[2][i],m[1].getAProp(m[2][i]))
  end repeat
end

on Open classInst
  me = classInst.new()
  me.OpenModule(#LingoF)
  repeat with i = 2 to the paramcount
    me.OpenModule(param(i))
  end repeat
  return me
end

on getModule __,module
  return __.getModuleAndFnList(module)[1]
end

on getModuleAndFnList __,module
  global gLingoF_fnModule
  
  if voidP(gLingoF_fnModule) then gLingoF_fnModule = [:]  
  
  if the runmode = "author" then
    if not voidP(gLingoF_fnModule[module]) then
      moduleMem = gLingoF_fnModule[module][3]
      moduleMemDate = gLingoF_fnModule[module][4]
      if voidP(moduleMem.modifiedDate) then modifDate = date(modifDate.year + 1, 1 ,1)
      else modifDate = moduleMem.modifiedDate
      if (modifDate > moduleMemDate) or ( (modifDate = moduleMemDate) and (modifDate.seconds > moduleMemDate.seconds)) then
        gLingoF_fnModule[module] = void
        gLingoF_fnModule.deleteProp(module)
      end if
    end if
  end if
  
  if voidP(gLingoF_fnModule[module]) then
    functions = []
    -- Import dependent modules
    moduleMember = member ("fnModule-"&string(module))
    inst = script(moduleMember).new()
    repeat with i = 1 to inst.count
      importedModule = inst.getPropAt(i)
      setProp(Inst,importedModule,getModule(__,importedModule))
    end repeat
    
    FirstFunctionIndex = i
    LastFunctionIndex = i-1
    
    -- Lambdamize handlers
    hndlers = inst.handlers()
    publishNextHandler = false
    repeat with i = 1 to hndlers.count()
      strHnd = string(hndlers[i])
      if (char 1 to 7 of strHnd ) = "public_" then
        publishNextHandler = true
        hndLength = strHnd.length
        repeat with j = hndLength-1 down to 9
          if char (j) of strHnd = "_" then exit repeat
        end repeat
        fname = symbol(char 8 to (j-1) of strHnd)
        
        argscount = integer(char (j+1) to hndLength of strHnd)
        
      else
        if publishNextHandler then
          if argscount>0 then fn = (script "scrLambdaFunction").new(hndlers[i],inst,argscount)
          else fn = call(hndlers[i],inst)
          setProp(Inst,fname,fn)
          functions.add(fname)
          LastFunctionIndex = LastFunctionIndex + 1
          publishNextHandler = false
          fn = void
        end if
      end if     
      
    end repeat
    
    -- set ancestor for debugging
    if the runmode = "author"then
      setProp(inst,#ancestor,(script "scrfnModule").new())
    end if
    -- cache the module
    gLingoF_fnModule.addProp(module,[Inst,functions,moduleMember,moduleMember.modifiedDate])
  end if
  return gLingoF_fnModule[module]
end

on getLambda __, module, function, pcount, p1,p2,classInstance
  firstParameterIsTheScriptInstance = not voidP(classInstance)
  asOperator = pcount-firstParameterIsTheScriptInstance
  if firstParameterIsTheScriptInstance then leftValue = p2
  else leftValue = p1
  
  n = getModule(__,module)
  f = n.getaProp(function)
  --------------
  if leftValue = LingoF() then
    leftValue = param(6)
    asOperator = asOperator-1
  end if
  --------------
  if (asOperator) then return f[leftValue]
  else return f
end

on newVar
  return (script "scrVarClosure").new()
end


------ Shortcut handlers ----------
on getShortcut __,shortcut,pcount,inst
  AsControlStructure = false
  case shortcut of
    #$ : fn = LingoF().open(#Shortcuts).shortcut_ApplyList
    #! : fn = LingoF().open(#Shortcuts).shortcut_CreateList 
    #fun : 
      AsControlStructure = true
      LingoExpressionFN = (script "scrLambdaFunction").new(#LingoExpression,(script "fnModule-Shortcuts"),pCount-(not voidP(Inst))+1)
      fn = LingoF().open(#Shortcuts).fun [LingoExpressionFN]
  end case
  return (script ("scrLingoF_ParamReader")).new(fn,pCount,inst,AsControlStructure)
end

---------------
-- SHORTCUTS --
---------------

on var
  return LingoF().newVar()
end

on _ classInst
  return LingoF().getLambda(#LingoF,#Skip, the paramcount,param(1),param(2),classInst)
end

on fun classInst
  o = LingoF().getShortcut(#fun,the paramcount,classInst)
  repeat while o.process(param(o.pindex))
  end repeat
  return o.getValue()
end

on $ classInst
  o = LingoF().getShortcut(#$,the paramcount,classInst)
  repeat while o.process(param(o.pindex))
  end repeat
  return o.getValue()
end

on ! classInst
  o = LingoF().getShortcut(#!,the paramcount,classInst)
  repeat while o.process(param(o.pindex))
  end repeat
  return o.getValue()
end

on @ classInst
  return LingoF().getLambda(#LingoF,#Compose, the paramcount,param(1),param(2),classInst)
end